package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    size = 3
)

// 初始化游戏板
func initBoard() [][]int {
    board := make([][]int, size)
    for i := range board {
        board[i] = make([]int, size)
    }
    //这个地方需要进行 TODO 
    numbers := rand.Perm(9)[:8] // 生成1-8的随机排列，并去掉最后一个元素（用作空位）
    fmt.Println("numbers: ", numbers)
    emptyIdx := rand.Intn(size*size) // 随机选择一个空位位置
    fmt.Println("emptyIdx: ", emptyIdx)
    for i, num := range numbers {
        row, col := i/size, i%size
        if i == emptyIdx {
            board[row][col] = 0 // 空位
        } else {
            board[row][col] = num
        }
    }
    return board
}

// 打印游戏板
func printBoard(board [][]int) {
    for _, row := range board {
        for _, val := range row {
            fmt.Printf("%d ", val)
        }
        fmt.Println()
    }
}

// 获取空位位置 这里可以在初始化时就获取相应的空位置
func getEmptyPosition(board [][]int) (int, int) {
    for i, row := range board {
        for j, val := range row {
            if val == 0 {
                return i, j
            }
        }
    }
    return -1, -1
}

// 移动空位（上、下、左、右）
func moveEmpty(board [][]int, direction string) bool {
    row, col := getEmptyPosition(board)
    if row == -1 || col == -1 {
        return false
    }

    newRow, newCol := row, col
    switch direction {
    case "up":
        newRow--
    case "down":
        newRow++
    case "left":
        newCol--
    case "right":
        newCol++
    default:
        return false
    }

    // 检查新位置是否在边界内
    if newRow >= 0 && newRow < size && newCol >= 0 && newCol < size {
        // 交换空位和新位置的值
        board[row][col], board[newRow][newCol] = board[newRow][newCol], board[row][col]
        // 这里变化一下空位的位置 并且值进行变化  TODO 
        return true
    }
    return false
}

// 检查游戏是否完成
func isCompleted(board [][]int) bool {
    for i := 0; i < size; i++ {
        for j := 0; j < size; j++ {
            if board[i][j] != 0 && board[i][j] != i*size+j+1 {
                return false
            }
        }
    }
    return true
}

func main() {
    rand.Seed(time.Now().UnixNano())
    board := initBoard()

    for {
        printBoard(board)
        var move string
        fmt.Print("Enter move (up, down, left, right) or 'quit' to exit: ")
        fmt.Scan(&move)

        if move == "quit" {
            break
        }

        if moveEmpty(board, move) {
            if isCompleted(board) {
                printBoard(board)
                fmt.Println("Congratulations! You've solved the puzzle!")
                break
            }
        } else {
            fmt.Println("Invalid move. Try again.")
        }
    }
}